﻿/*
 *   NumericFunctionsTests.cs
 *   Copyright (c) 2011 - BitFox Software and Ricardo Federico Villafañes
 *   Contact: federvillaf@hotmail.com
 *   
 *   Licensing: This product is covered by Microsoft Reciprocal License (MS-RL)
 *              see https://bitfoxeval.codeplex.com/license
*/

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using BitFox.Evaluator;

namespace TestEvaluator
{
    /// <summary>
    /// Tests related, mainly, to numeric functions
    /// </summary>
    [TestClass]
    public class NumericFunctionsTests
    {
        // The evaluator to use in tests
        Evaluator eval = new Evaluator();

        /// <summary>
        /// Empty constructor
        /// </summary>
        public NumericFunctionsTests()
        {
        }

        /// <summary>
        /// The context under which tests are runned.
        ///</summary>
        public TestContext TestContext { get; set; }

        [TestMethod]
        public void TestABS()
        {
            Assert.AreEqual(11m, (decimal)eval.Compile("abs(11)").Run());
            Assert.AreEqual(11m, (decimal)eval.Compile("abs(-11)").Run());
            Assert.AreEqual(11.23m, (decimal)eval.Compile("abs(11.23)").Run());
            Assert.AreEqual(11.23m, (decimal)eval.Compile("abs(-11.23)").Run());
        }

        [TestMethod]
        public void TestACOS()
        {
            Assert.AreEqual((decimal)Math.PI, (decimal)eval.Compile("acos(-1)").Run());
            Assert.AreEqual((decimal)(Math.PI / 2), (decimal)eval.Compile("acos(0)").Run());
            Assert.AreEqual(0m, (decimal)eval.Compile("acos(1)").Run());
        }

        [TestMethod]
        public void TestASIN()
        {
            Assert.AreEqual((decimal)(-Math.PI / 2), (decimal)eval.Compile("asin(-1)").Run());
            Assert.AreEqual(0m, (decimal)eval.Compile("asin(0)").Run());
            Assert.AreEqual((decimal)(Math.PI / 2), (decimal)eval.Compile("asin(1)").Run());
        }

        [TestMethod]
        public void TestATAN()
        {
            Assert.AreEqual(1.55079899282175m, (decimal)eval.Compile("atan(50)").Run());
            Assert.AreEqual(0m, (decimal)eval.Compile("atan(0)").Run());
            Assert.AreEqual(-1.55079899282175m, (decimal)eval.Compile("atan(-50)").Run());
        }

        [TestMethod]
        public void TestCEILING()
        {
            Assert.AreEqual(2m, (decimal)eval.Compile("ceiling(1.1)").Run());
            Assert.AreEqual(2m, (decimal)eval.Compile("ceiling(1.9)").Run());
            Assert.AreEqual(-1m, (decimal)eval.Compile("ceiling(-1.1)").Run());
            Assert.AreEqual(-1m, (decimal)eval.Compile("ceiling(-1.9)").Run());
            Assert.AreEqual(3m, (decimal)eval.Compile("ceiling(3)").Run());
        }

        [TestMethod]
        public void TestFLOOR()
        {
            Assert.AreEqual(1m, (decimal)eval.Compile("floor(1.1)").Run());
            Assert.AreEqual(1m, (decimal)eval.Compile("floor(1.9)").Run());
            Assert.AreEqual(-2m, (decimal)eval.Compile("floor(-1.1)").Run());
            Assert.AreEqual(-2m, (decimal)eval.Compile("floor(-1.9)").Run());
            Assert.AreEqual(3m, (decimal)eval.Compile("floor(3)").Run());
        }

        [TestMethod]
        public void TestFV()
        {
            Assert.AreEqual(27887.93210741785m, (decimal)eval.Compile("fv(500,0.00625,48)").Run());
            Assert.AreEqual(27887.93210741785m, (decimal)eval.Compile("fv(500,0.00625,-48)").Run());
            Assert.AreEqual(27887.93210741785m, (decimal)eval.Compile("fv(500,-0.00625,48)").Run());
            Assert.AreEqual(-27887.93210741785m, (decimal)eval.Compile("fv(-500,0.00625,48)").Run());
            Assert.AreEqual(0, (decimal)eval.Compile("fv(0,0.00625,48)").Run());
            Assert.AreEqual(0, (decimal)eval.Compile("fv(500,0,48)").Run());
            Assert.AreEqual(0, (decimal)eval.Compile("fv(-500,0.00625,0)").Run());
        }

        [TestMethod]
        public void TestINT()
        {
            Assert.AreEqual(1m, (decimal)eval.Compile("int(1.41)").Run());
            Assert.AreEqual(1m, (decimal)eval.Compile("int(1.61)").Run());
            Assert.AreEqual(1m, (decimal)eval.Compile("int(1)").Run());
            Assert.AreEqual(-1m, (decimal)eval.Compile("int(-1.41)").Run());
            Assert.AreEqual(-1m, (decimal)eval.Compile("int(-1.61)").Run());
            Assert.AreEqual(-1m, (decimal)eval.Compile("int(-1)").Run());
            Assert.AreEqual(0m, (decimal)eval.Compile("int(0)").Run());
        }

        [TestMethod]
        public void TestMAX()
        {
            Assert.AreEqual(24m, (decimal)eval.Compile("max(1,3,5,24,12,11)").Run());
            Assert.AreEqual("AC", (string)eval.Compile("max('AA','AC','AB')").Run());
            Assert.AreEqual(new DateTime(2009,1,31), (DateTime)eval.Compile("max({^2009/01/31}, {^2009/01/15}, {^2009/01/28})").Run());
            Assert.IsTrue((bool)eval.Compile("max(.f., .f., .t., .f.)").Run());
            Assert.IsFalse((bool)eval.Compile("max(.f., .f., .f., .f.)").Run());
        }

        [TestMethod]
        public void TestMIN()
        {
            Assert.AreEqual(3m, (decimal)eval.Compile("min(11,3,5,24,12,11)").Run());
            Assert.AreEqual("AA", (string)eval.Compile("min('AA','AC','AB')").Run());
            Assert.AreEqual(new DateTime(2009, 1, 15), (DateTime)eval.Compile("min({^2009/01/31}, {^2009/01/15}, {^2009/01/28})").Run());
            Assert.IsTrue((bool)eval.Compile("min(.t., .t., .t., .t.)").Run());
            Assert.IsFalse((bool)eval.Compile("min(.f., .f., .t., .f.)").Run());
        }

        [TestMethod]
        public void TestMOD()
        {
            Assert.AreEqual(0m, (decimal)eval.Compile("mod(12,3)").Run());
            Assert.AreEqual(1m, (decimal)eval.Compile("mod(13,3)").Run());
            Assert.AreEqual(2m, (decimal)eval.Compile("mod(14,3)").Run());
            Assert.AreEqual(2.4m, (decimal)eval.Compile("mod(14.4,3)").Run());
            Assert.AreEqual(0.6m, (decimal)eval.Compile("mod(-14.4,3)").Run());
        }

        [TestMethod]
        public void TestROUND()
        {
            Assert.AreEqual(123.45m, (decimal)eval.Compile("round(123.445, 2)").Run());
            Assert.AreEqual(123.44m, (decimal)eval.Compile("round(123.444, 2)").Run());
            Assert.AreEqual(123.45m, (decimal)eval.Compile("round(123.448, 2)").Run());
            Assert.AreEqual(12300.0m, (decimal)eval.Compile("round(12345.448, -2)").Run());
            Assert.AreEqual(12345m, (decimal)eval.Compile("round(12345.448, 0)").Run());
        }

        [TestMethod]
        public void TestDTOR()
        {
            Assert.AreEqual(0.785398163397448m, (decimal)eval.Compile("DTOR(45)").Run());
            Assert.AreEqual(0.797615468161409m, (decimal)eval.Compile("DTOR(45.7)").Run());
            Assert.AreEqual(-17.4532925199433m, (decimal)eval.Compile("DTOR(-1000)").Run());
        }

        [TestMethod]
        public void TestRTOD()
        {
            Assert.AreEqual(45m, (decimal)eval.Compile("RTOD(0.785398163397448)").Run());
            Assert.AreEqual(45.7m, (decimal)eval.Compile("RTOD(0.797615468161409)").Run());
            Assert.AreEqual(-1000m, (decimal)eval.Compile("RTOD(-17.4532925199433)").Run());
        }
    }
}
